"""
浅拷贝：
浅拷贝 ：创建一个新对象，但是新对象中的元素只是原对象中元素的引用。如果原对象中的元素是可变类型（如列表、字典等），
那么修改新对象中的元素会影响原对象；如果原对象中的元素是不可变类型（如整数、字符串等），则不会影响原对象。
    1. 只拷贝第一层数据
    2. 拷贝的是地址
    3. 浅拷贝是对可变数据类型的第一层数据进行拷贝，对不可变数据类型的第一层数据进行拷贝


深拷贝：
深拷贝 ：创建一个新对象，并且递归地复制原对象中的所有元素。修改新对象中的元素不会影响原对象。
    1. 拷贝所有数据
    2. 拷贝的是数据
    3. 深拷贝是对所有数据进行拷贝，对可变数据类型的第一层数据进行拷贝，对不可变数据类型的第一层数据进行拷贝
    4. 深拷贝是对所有数据进行拷贝，对可变数据类型的第一层数据进行拷贝，对不可变数据类型的第一层数据进行拷贝


等号赋值：
等号赋值 ：只是将变量名指向同一个对象，不涉及对象本身的复制。如果修改了其中一个变量指向的对象，另一个变量指向的对象也会随之改变。
    1. 拷贝的是地址
    2. 等号赋值是对可变数据类型的第一层数据进行拷贝，对不可变数据类型的第一层数据进行拷贝
    3. 等号赋值是对所有数据进行拷贝，对可变数据类型的第一层数据进行拷贝，对不可变数据类型的第一层数据进行拷贝
"""
#  深拷贝
import copy
# 定义一个列表
a = [1, 2, [3, 4]]
# 深拷贝
b = copy.deepcopy(a)
# 修改b中的元素
b[0] = 100
b[2][0] = 300
print("a:", a)  # 输出：a: [1, 2, [3, 4]]
print("b:", b)  # 输出：b: [100, 2, [300, 4]]


# 浅拷贝
import copy
# 定义一个列表
a = [1, 2, [3, 4]]
# 浅拷贝
b = copy.copy(a)
# 修改b中的元素
b[0] = 100
b[2][0] = 300
print("a:", a)  # 输出：a: [1, 2, [300, 4]]
print("b:", b)  # 输出：b: [100, 2, [300, 4]]


# 等号赋值
# 定义一个列表
a = [1, 2, [3, 4]]
# 等号赋值
b = a
# 修改b中的元素
b[0] = 100
b[2][0] = 300
print("a:", a)  # 输出：a: [100, 2, [300, 4]]
print("b:", b)  # 输出：b: [100, 2, [300, 4]]

"""
不可变类型
int
float
bool
str
NoneType
tuple

可变类型
list
dict
set
"""

import copy

# d0 = {
# 	"id": 101,
# 	"name": "qiku",
# 	"address": {
# 		"id": 1,
# 		"name": "东三街"
# 	}
# }

# 等号赋值：完全等同于同一个
# d1 = d0
# print(id(d0), id(d1))
# print(id(d0["address"]), id(d1["address"]))
# d0["address"]["name"] = "黄河路"
# d0["id"] = 1001
# print(d1)


# 浅拷贝：不可变类型，拷贝值，可变类型拷贝地址    不分独立的两个对象
# d2 = copy.copy(d0)
# d2 = d0.copy()
# print(id(d0), id(d2))
# print(id(d0["address"]), id(d2["address"]))
# d0["id"] = 1001
# d0["address"]["name"] = "黄河路"
# print(d2)


# 深拷贝：不可变类型、可变类型 全部拷贝值    完全独立的两个对象
# d3 = copy.deepcopy(d0)
# print(id(d0), id(d3))
# print(id(d0["address"]), id(d3["address"]))
# d0["id"] = 1001
# d0["address"]["name"] = "黄河路"
# print(d3)



